const { Service } = require("uni-cloud-router");
const CryptoJS = require('crypto-js'); 
const db = uniCloud.database();
const pointPlatformCode = "JF0002"//积分编码
const earnCode = "JFHQ0004"//积分获取规则编码
const detailRuleCode = "DHGZ000001"//兑换规则编码
const baseUrl = 'http://yfzx.dysmt.cn/openapi/v1/city-oper-point-service'
//这里是演示了家长学院的部分后端接口（不含拿到uid和phone对应关系后写入数据库的逻辑）
const keys = {
	smt:{
		clientId:'hU7XXXXXXXXXI5m',//市民通正式环境clientId
		secret:'yH9nXXXXXXXXXM0l'//市民通正式环境secret
	},
	jiaoyuMain:{//教育
		clientId:'8NXXXXXXXXX10',
		secret:'B6WG8CXXXXXXXXXBXXXXXXXXXIDE'
	},
	jiaoyu:{//教育测试
		clientId:'9J5XXXXXXXXXR0NF',
		secret:'8C8T4XXXXXXXXX9VTXXXXXXXXX44P'
	}
} 
module.exports = class httpService extends Service {
	async face_result_query(ctx){		
		let apiUidsCheck = await this.smtOpenApi('https://openapi.dysmt.cn/openapi/v1/dysmt-service/wx/face_result_query',//批量查询市民通id
		keys.smt.clientId,keys.smt.secret,ctx.data)
		return apiUidsCheck
	}
	async smtUserInfo(ctx){//code换用户信息,返回token 手机号和smtID
		//前端可用
		//https://XXXXXXXXX.XXXXXXXXX.cc/apim/http/smtUserInfo
		//{"code":"4Ox7k1"}
		let apiTokenCheck = await uniCloud.httpclient.request("https://auths.dysmt.cn/oauth/token?code="+ctx.data.code+"&client_id=72398458XXXXXXXXXXXXXXXXXX3157&client_secret=490XXXXXXXXXXXXXXXXXX7512&grant_type=authorization_code&redirect_uri=https://jy.dycic.net", {
			method: "POST",
			dataType: 'json' ,// 指定返回值为json格式，自动进行parse  
			headers: {
				"Content-Type": "application/json",
				"Accept":"application/json, text/plain, */*"
			},
		});
		let apiAuthCheck = await uniCloud.httpclient.request("https://authr.dysmt.cn/resource/user/userinfo?access_token="+apiTokenCheck.data.access_token, {
			method: "POST",
			dataType: 'json' ,// 指定返回值为json格式，自动进行parse  
			headers: {
				"Content-Type": "application/json",
				"Accept":"application/json, text/plain, */*"
			},
		});
		let datas = {}
		datas.smtId = apiAuthCheck.data.content.id
		datas.phone = apiAuthCheck.data.content.phone
		datas.token = apiAuthCheck.data.content.userToken
		return datas
	}
	async smtAuth(token,id){//判断是否鉴权，内部调用
		//!!!!是否开启市民通token鉴权
		//这里如果设为true是，需要用户前端传入用户token，,"token":"eyJh....."
		const authActived = false//false，false将会在前端兑换等操作时跳过鉴权
		if(authActived){
			let apiCheck = await uniCloud.httpclient.request("https://authr.dysmt.cn/resource/user/userinfo?access_token="+token, {
				method: "POST",
				dataType: 'json' ,// 指定返回值为json格式，自动进行parse  
				headers: {
					"Content-Type": "application/json",
					"Accept":"application/json, text/plain, */*"
				},
			});
			if(apiCheck.data.content.id==id){
				return true
			}
			else{
				return false
			}
		}
		else{
			return true
		}
	}
	async smtOpenApi(url,clientId,secret,data){//市民通/城市运营中台openapi执行，内部调用
		const body = data
		let timestamp = new Date().getTime()
		let sign = CryptoJS.SHA512('clientId='+clientId+'&nonce='+timestamp+'&timestamp='+timestamp+'&version=1.0.0&'+JSON.stringify(body)+'&'+secret).toString()
		let apiCheck = await uniCloud.httpclient.request(url, {
			method: "POST",
			data: body,  
			dataType: 'json' ,// 指定返回值为json格式，自动进行parse  
			headers: {
				"Content-Type": "application/json",
				"Accept":"application/json, text/plain, */*",
				"version":"1.0.0",
				"clientId":clientId,
				"nonce":timestamp,
				"timestamp":timestamp,
				"sign":sign
			},
		});
		return apiCheck
	}
	
	async increaseCredits(ctx){//接收学分增长通知，判断用户是否已初始化，若已初始化，则增加，若未初始化，则初始化式增加积分
		//不可用于前端
		//http://XXXXXXXXX.XXXXXXXXX.cc/point/http/increaseCredits
		//{"parentMobile":"13XXXXXXXXX01","point":10}
		/*
		{
		    "msg": "发积分成功",
		    "data": {
		        "parentMobile": "137XXXXXXXXX1",
		        "point": 10
		    }
		}
		*/
		const userInfo = await db.collection('jiaoyu').where({'parentMobile':ctx.data.parentMobile}).get()
		if(userInfo.data.length == 0){//数据库中没有此用户
			let datas = {}
			datas.phones = []
			datas.phones.push(ctx.data.parentMobile)
			let apiUidsCheck = await this.smtOpenApi('https://openapi.dysmt.cn/openapi/v1/dysmt-service/inactive_user/get_uids',//批量查询市民通id
			keys.smt.clientId,keys.smt.secret,datas)
			let apiInitCheck = await this.smtOpenApi(baseUrl+'/external_api/member/init',//初始化用户
			keys.jiaoyu.clientId,keys.jiaoyu.secret,{
				"smtId":apiUidsCheck.data.data[0].uid,"pointPlatformCode":pointPlatformCode,"totalPoint":ctx.data.point
			})
			if(apiInitCheck.data.msg == "succ"){
				const createUser = await db.collection('jiaoyu').add({
					smtId:apiUidsCheck.data.data[0].uid,
					parentMobile:ctx.data.parentMobile,
					count:ctx.data.point,
					last_update_date:new Date(),
					create_date:new Date(),
					initialed:1//是否已初始化，0为否，1为是
				});
				return {msg:"初始化成功",data:ctx.data}
			}else{
				return {msg:"出错了，初始化未成功"}
			}
		}else if(userInfo.data.length == 1 && userInfo.data[0].initialed == 0){//有此用户但未初始化
			let apiInitCheck = await this.smtOpenApi(baseUrl+'/external_api/member/init',//初始化用户
			keys.jiaoyu.clientId,keys.jiaoyu.secret,{
				"smtId":userInfo.data[0].smtId,"pointPlatformCode":pointPlatformCode,"totalPoint":ctx.data.point+userInfo.data[0].count
			})
			if(apiInitCheck.data.msg == "succ"){
				const updateUser = await db.collection('jiaoyu').where({'smtId':userInfo.data[0].smtId}).update({
					last_update_date:new Date(),
					initialed:1//是否已初始化，0为否，1为是
				})
				return {msg:"初始化成功",data:ctx.data}
			}else{
				return {msg:"出错了，初始化未成功"}
			}
		}
		else if(userInfo.data[0].initialed == 1){//有此用户，发行积分
			let apiEarnCheck = await this.smtOpenApi(baseUrl+'/external_api/point/earn',//发行积分
			keys.jiaoyu.clientId,keys.jiaoyu.secret,{
				"smtId":userInfo.data[0].smtId,"code":earnCode,"point":ctx.data.point
			})
			if(apiEarnCheck.data.msg == "succ"){
				const updateUser = await db.collection('jiaoyu').where({'smtId':userInfo.data[0].smtId}).update({
					last_update_date:new Date(),					
					count:ctx.data.point+userInfo.data[0].count
				})
				return {msg:"发积分成功",data:ctx.data}
			}else{
				return {msg:"出错了，发积分未成功"}
			}
		}
	}
	async intialUser(ctx){//对数据库中的用户进行初始化
		//不可用于前端
		//api：http://XXXXXXXXX.XXXXXXXXX.cc/point/http/intialUser
		//body：{"skip":1,"limit":2}
		const skip = ctx.data.skip // 跳过前skip条
		const limit = ctx.data.limit // 获取limit条
		const intialUserList = await db.collection('jiaoyu').where({initialed:0}).skip(skip).limit(limit).get()
		for(let i = 0;i < intialUserList.data.length; i++){
			let apiCheck = await this.smtOpenApi(baseUrl+'/external_api/member/init',//初始化用户
			keys.jiaoyu.clientId,keys.jiaoyu.secret,{
				"smtId":intialUserList.data[i].smtId,"pointPlatformCode":pointPlatformCode,"totalPoint":intialUserList.data[i].count
			})
			if(apiCheck.data.msg == "succ"){
				const updateUser = await db.collection('jiaoyu').where({'smtId':intialUserList.data[i].smtId}).update({
					last_update_date:new Date(),
					initialed:1//是否已初始化，0为否，1为是
				})
			}
		}
		let updateList = intialUserList.data
		if(updateList.length > 0){return {msg:"执行中，共提交"+updateList.length+"人"}}else{
			return {msg:"无需初始化用户"}
		}
	}	
	async getticket(ctx){//获取公众号ticket，需要配合定时任务，见云函数wxofficialacconut
		let tokens = await db.collection('tokens').where({'_id':"6583a8cae0ec190274b8a0d2"}).get()
		return tokens
	}
	async bindUser(ctx){//输入手机号和积分余额，为其绑定市民通ID并计入数据库，可输入单个或多个,此接口无重复校验，仅作为首次导入使用
		//不可用于前端
		//api：http://XXXXXXXXX.XXXXXXXXX.cc/point/http/bindUser
		//body（count是积分余额）：[{"phone":"137XXXXXXXXX01","count":10},{"phone":"1809XXXXXXXXX","count":10},{"phone":"1851XXXXXXXXX","count":10}]
		/*

		*/
		let checkList = {}
		checkList.phones = []
		let dataList = []
		if(ctx.data.length > 500){return "此接口无批量个数限制，但市民通接口有500限制，因此将上限设置为500"}
		else{
			ctx.data.forEach((item,index)=>{
				checkList.phones.push(item.phone)			
			})//转换市民通接口需要的格式{"phones":["13703XXXXXXXXX1","1809XXXXXXXXX","185XXXX7355"]}
			let apiCheck = await this.smtOpenApi('https://openapi.dysmt.cn/openapi/v1/dysmt-service/inactive_user/get_uids',//批量查询市民通id
			keys.smt.clientId,keys.smt.secret,checkList)
			apiCheck.data.data.forEach((item,index)=>{//这里写拿到uid和phone对应关系后写入数据库
				dataList.push({
					smtId:item.uid,
					parentMobile:item.phone,
					count:ctx.data[index].count,
					last_update_date:new Date(),
					create_date:new Date(),
					initialed:0//是否已初始化，0为否，1为是
				})			
			})
			const createUser = await db.collection('jiaoyu').add(dataList);
			return createUser
		}
		
	}
	async memberInfo(ctx){//列出当前用户积分余额和兑换规则
		let apiCheck = await this.smtOpenApi(baseUrl+'/external_api/member/info',
		keys.jiaoyu.clientId,keys.jiaoyu.secret,ctx.data)
		//前端可用
		//https://XXXXXXXXX.XXXXXXXXX.cc/apim/http/memberInfo
		//{"smtId":"3fff3eaf94114e7ebc4d4b4215b842cb"}
		/*
		{
		    "code": "0",
		    "msg": "succ",
		    "data": {
		        "smtId": "3fff3eaf94114e7ebc4d4b4215b842cb",
		        "name": "白帆",
		        "phone": "18XXXXXXXXX405",
		        "pointInfos": [
		            {
		                "point": 10,
		                "pointPlatformName": "测试积分",
		                "pointPlatformCode": "JF0003"
		            },
		            {
		                "point": 9,
		                "pointPlatformName": "家长学院积分",
		                "pointPlatformCode": "JF0002"
		            }
		        ],
		        "currentPointInfo": {
		            "point": 9,
		            "pointPlatformName": "家长学院积分",
		            "pointPlatformCode": "JF0002"
		        },
		        "detailRule": {
		            "code": "DHGZ000001",
		            "pointOutputTypeCode": "JFXH0003",
		            "pointOutputTypeName": "兑换心加商城积分",
		            "pointInputTypeCode": "JFHQ0003",
		            "pointInputTypeName": "被兑换心加商城积分",
		            "ratioOutput": 1,
		            "ratioInput": 10
		        }
		    }
		}
		*/
		const codeIndex = apiCheck.data.data.pointInfos.findIndex((item) => {return item.pointPlatformCode === pointPlatformCode})
		apiCheck.data.data.currentPointInfo = apiCheck.data.data.pointInfos[codeIndex]
		let ruleCheck = await this.smtOpenApi(baseUrl+'/external_api/exchange/detail',
		keys.jiaoyu.clientId,keys.jiaoyu.secret,{"code": detailRuleCode})//兑换规则编码
		apiCheck.data.data.detailRule = ruleCheck.data.data
		let datas = apiCheck.data
		return datas
	}
	async pointExchange(ctx){
		//开启鉴权的条件下前端可用
		//https://XXXXXXXXX.XXXXXXXXX.cc/apim/http/pointExchange
		//{"smtId":"000005d92b9346c690af23589a249af9","num":1,"token":""}
		/*
		{"smtId":"000005d92b9346c690af23589a249af9","num":1,"token":""}

		*/
		if(await this.smtAuth(ctx.data.token,ctx.data.smtId)){//鉴权，根据市民通ID判断是否和被操作用户id一致
			let apiCheck = await this.smtOpenApi(baseUrl+'/external_api/point/exchange',
			keys.jiaoyu.clientId,keys.jiaoyu.secret,{
				"smtId":ctx.data.smtId,"code":detailRuleCode,"num":ctx.data.num
			})
			let datas = apiCheck.data
			return datas
		}
		else{
			return {msg:"市民通TOKEN解析出的用户与积分操作用户不一致","code": "0","data": null}
		}
	}
	async addToken(ctx){//城市运营中台积分平台相关操作
		let tokens = await db.collection('tokens').add({
			currentAccessToken:"",
			currentJsapiTicket:"",
			accessTokenRefreshTime:new Date()
		})
		return tokens
	}
	async cityOperPoint(ctx){//城市运营中台积分平台相关操作
		//开启鉴权的条件下前端可用
		if(await this.smtAuth(ctx.data.token,ctx.data.smtId)){//鉴权，根据市民通ID判断是否和被操作用户id一致
			let apiCheck = await this.smtOpenApi(baseUrl+'/external_api'+ctx.data.route,
			keys.jiaoyu.clientId,keys.jiaoyu.secret,ctx.data)
			let data = apiCheck.data
			/*
			{"smtId":"3fff3eaf94114e7ebc4d4b4215b842cb","pointPlatformCode":"JFHQ0004","route":"/member/info"}
			{"smtId":"3fff3eaf94114e7ebc4d4b4215b842cb","code":"JFHQ0004","point":1,"route":"/point/earn"}
			{"smtId":"000005d92b9346c690af23589a249af9","pointPlatformCode":"JF0001","totalPoint":1,"route":"/member/init"}
			{"smtId":"000005d92b9346c690af23589a249af9","code":"DHGZ000001","num":1,"route":"/point/exchange"}
			已知的一些坑，1、初始化用户的积分不能为0，2、用户在被兑换平台必须也进行了初始化（当前先只考虑两边都已经初始化的情况）
			*/
			return data
		}
		else{
			return {msg:"市民通TOKEN解析出的用户与积分操作用户不一致","code": "0","data": null}
		}
		
	}
}